Fix for #137551, by Robert Ögren:
authorTor Lillqvist <tml@iki.fi>
Thu, 11 Nov 2004 22:00:11 +0000 (22:00 +0000)
committerTor Lillqvist <tml@src.gnome.org>
Thu, 11 Nov 2004 22:00:11 +0000 (22:00 +0000)
2004-11-11  Tor Lillqvist  <tml@iki.fi>

Fix for #137551, by Robert Ögren:

* gdk/win32/gdkevents-win32.c (generate_focus_event): New function.

(gdk_keyboard_grab, gdk_keyboard_ungrab): Generate focus change
events.

(gdk_event_translate): Check for keyboard grabs and not pointer
grabs when handling WM_{SET,KILL}FOCUS. Use generate_focus_event().

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/win32/gdkevents-win32.c

index 94a5bcd069239a9af7fd94e38040150aefb81bb7..17a99dd7572d8e83915a68c2ffd45fc05c75cae1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2004-11-11  Tor Lillqvist  <tml@iki.fi>
+
+       Fix for #137551, by Robert Ögren:
+
+       * gdk/win32/gdkevents-win32.c (generate_focus_event): New function.
+
+       (gdk_keyboard_grab, gdk_keyboard_ungrab): Generate focus change
+       events.
+       
+       (gdk_event_translate): Check for keyboard grabs and not pointer
+       grabs when handling WM_{SET,KILL}FOCUS. Use generate_focus_event().
+
 2004-11-11  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkuimanager.c (update_node): Remove two more places
index 94a5bcd069239a9af7fd94e38040150aefb81bb7..17a99dd7572d8e83915a68c2ffd45fc05c75cae1 100644 (file)
@@ -1,3 +1,15 @@
+2004-11-11  Tor Lillqvist  <tml@iki.fi>
+
+       Fix for #137551, by Robert Ögren:
+
+       * gdk/win32/gdkevents-win32.c (generate_focus_event): New function.
+
+       (gdk_keyboard_grab, gdk_keyboard_ungrab): Generate focus change
+       events.
+       
+       (gdk_event_translate): Check for keyboard grabs and not pointer
+       grabs when handling WM_{SET,KILL}FOCUS. Use generate_focus_event().
+
 2004-11-11  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkuimanager.c (update_node): Remove two more places
index 94a5bcd069239a9af7fd94e38040150aefb81bb7..17a99dd7572d8e83915a68c2ffd45fc05c75cae1 100644 (file)
@@ -1,3 +1,15 @@
+2004-11-11  Tor Lillqvist  <tml@iki.fi>
+
+       Fix for #137551, by Robert Ögren:
+
+       * gdk/win32/gdkevents-win32.c (generate_focus_event): New function.
+
+       (gdk_keyboard_grab, gdk_keyboard_ungrab): Generate focus change
+       events.
+       
+       (gdk_event_translate): Check for keyboard grabs and not pointer
+       grabs when handling WM_{SET,KILL}FOCUS. Use generate_focus_event().
+
 2004-11-11  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkuimanager.c (update_node): Remove two more places
index 94a5bcd069239a9af7fd94e38040150aefb81bb7..17a99dd7572d8e83915a68c2ffd45fc05c75cae1 100644 (file)
@@ -1,3 +1,15 @@
+2004-11-11  Tor Lillqvist  <tml@iki.fi>
+
+       Fix for #137551, by Robert Ögren:
+
+       * gdk/win32/gdkevents-win32.c (generate_focus_event): New function.
+
+       (gdk_keyboard_grab, gdk_keyboard_ungrab): Generate focus change
+       events.
+       
+       (gdk_event_translate): Check for keyboard grabs and not pointer
+       grabs when handling WM_{SET,KILL}FOCUS. Use generate_focus_event().
+
 2004-11-11  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkuimanager.c (update_node): Remove two more places
index 03b742133220edbc9222e36ab33cd25d62424213..8cc9fbdfca7771784b94c9655e3de4c2e6bb2829 100644 (file)
@@ -112,6 +112,9 @@ static gboolean gdk_event_dispatch (GSource     *source,
                                    GSourceFunc  callback,
                                    gpointer     user_data);
 
+static void append_event (GdkDisplay *display,
+                         GdkEvent   *event);
+
 /* Private variable declarations
  */
 
@@ -230,6 +233,19 @@ _gdk_win32_get_next_tick (gulong suggested_tick)
     return cur_tick = suggested_tick;
 }
 
+static void
+generate_focus_event (GdkWindow *window,
+                     gboolean   in)
+{
+  GdkEvent *event;
+
+  event = gdk_event_new (GDK_FOCUS_CHANGE);
+  event->focus_change.window = window;
+  event->focus_change.in = in;
+
+  append_event (gdk_drawable_get_display (window), event);
+}
+
 static LRESULT 
 inner_window_procedure (HWND   hwnd,
                        UINT   message,
@@ -716,6 +732,8 @@ gdk_keyboard_grab (GdkWindow *window,
                   gboolean   owner_events,
                   guint32    time)
 {
+  GdkWindow *real_focus_window, *grab_focus_window;
+
   gint return_val;
   
   g_return_val_if_fail (window != NULL, 0);
@@ -733,7 +751,31 @@ gdk_keyboard_grab (GdkWindow *window,
     return_val = GDK_GRAB_ALREADY_GRABBED;
 
   if (return_val == GDK_GRAB_SUCCESS)
-    k_grab_window = window;
+    {
+      k_grab_window = window;
+
+      if (!k_grab_owner_events)
+       {
+         real_focus_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) GetFocus ());
+         if (real_focus_window)
+           real_focus_window = gdk_window_get_toplevel (real_focus_window);
+         grab_focus_window = gdk_window_get_toplevel (k_grab_window);
+         if (real_focus_window != grab_focus_window)
+           {
+             /* Generate events for focus change from the window that really
+              * has focus to the grabber.
+              */
+             if (real_focus_window && !GDK_WINDOW_DESTROYED (real_focus_window)
+                 && (((GdkWindowObject *) real_focus_window)->event_mask
+                     & GDK_FOCUS_CHANGE_MASK))
+               generate_focus_event (real_focus_window, FALSE);
+
+             if (((GdkWindowObject *) grab_focus_window)->event_mask 
+                 & GDK_FOCUS_CHANGE_MASK)
+               generate_focus_event (grab_focus_window, TRUE);
+           }
+       }
+    }
   
   return return_val;
 }
@@ -742,10 +784,39 @@ void
 gdk_display_keyboard_ungrab (GdkDisplay *display,
                              guint32 time)
 {
+  GdkWindow *real_focus_window, *grab_focus_window;
+
   g_return_if_fail (display == gdk_display_get_default ());
 
   GDK_NOTE (EVENTS, g_print ("gdk_keyboard_ungrab\n"));
 
+  if (k_grab_window && !k_grab_owner_events)
+    {
+      real_focus_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) GetFocus ());
+      if (real_focus_window)
+       real_focus_window = gdk_window_get_toplevel (real_focus_window);
+      if (!GDK_WINDOW_DESTROYED (k_grab_window))
+       grab_focus_window = gdk_window_get_toplevel (k_grab_window);
+      else
+       grab_focus_window = NULL;
+      if (real_focus_window != grab_focus_window)
+       {
+         /* Generate events for focus change from grabber to the window that
+          * really has focus. Important for example if a new window is created
+          * while focus is grabbed.
+          */
+         if (grab_focus_window
+             && (((GdkWindowObject *) grab_focus_window)->event_mask
+                 & GDK_FOCUS_CHANGE_MASK))
+           generate_focus_event (grab_focus_window, FALSE);
+
+         if (real_focus_window && !GDK_WINDOW_DESTROYED (real_focus_window)
+             && (((GdkWindowObject *) real_focus_window)->event_mask
+                 & GDK_FOCUS_CHANGE_MASK))
+           generate_focus_event (real_focus_window, TRUE);
+       }
+    }
+
   k_grab_window = NULL;
 }
 
@@ -2831,7 +2902,7 @@ gdk_event_translate (GdkDisplay *display,
 
     case WM_SETFOCUS:
     case WM_KILLFOCUS:
-      if (p_grab_window != NULL && !p_grab_owner_events && !(p_grab_mask & GDK_FOCUS_CHANGE_MASK))
+      if (k_grab_window != NULL && !k_grab_owner_events)
        break;
 
       if (!(((GdkWindowObject *) window)->event_mask & GDK_FOCUS_CHANGE_MASK))
@@ -2840,12 +2911,7 @@ gdk_event_translate (GdkDisplay *display,
       if (GDK_WINDOW_DESTROYED (window))
        break;
 
-      event = gdk_event_new (GDK_FOCUS_CHANGE);
-      event->focus_change.window = window;
-      event->focus_change.in = (msg->message == WM_SETFOCUS);
-
-      append_event (display, event);
-
+      generate_focus_event (window, (msg->message == WM_SETFOCUS));
       return_val = TRUE;
       break;